import { signJwt, verifyJwt } from '../../helpers/jwt';
import log from '../../helpers/logger';
import { deleteFromCache, getFromCache, setExCache } from '../../helpers/redis';
import { PrismaClient } from '../../../../prisma/generated/uctoo'

const db = new PrismaClient({
  log: ['query', 'info', 'warn', 'error'],
});
import { AuthProvider, getUserById, getWechatUserById } from './../uctoo/uctoo_user';

export async function createSession(
  user_id: string,
  user_agent: string,
  ip: string,
  auth_provider: AuthProvider
) {
  const session = await db.uctoo_session.create({
    data: {
      user_id,
      user_agent,
      ip,
      auth_provider,
    },
  });
  setExCache(session.id, 9000, JSON.stringify(session));
  return session;
}

export async function removeSession(sessionId: string) {
  try {
    deleteFromCache(sessionId);
    await db.uctoo_session.delete({ where: { id: sessionId } });
  } catch (e) {
    log.error(e);
  }
}

export async function removeAllSessions(user_id: string) {
  await db.uctoo_session.deleteMany({ where: { user_id } });
}

export async function findSession(sessionId: string) {
  const cachedResponse = await getFromCache(sessionId);
  if (cachedResponse) {
    return cachedResponse;
  } else {
    const session = await db.uctoo_session.findUnique({
      where: {
        id: sessionId,
      },
    });
    setExCache(sessionId, 9000, JSON.stringify(session));
    return session;
  }
}

export async function updateSession(sessionId: string, data) {
  return db.uctoo_session.update({
    where: {
      id: sessionId,
    },
    data,
  });
}

export async function tokenRefresh(refresh_token: string) {
  const { decoded } = verifyJwt(refresh_token);
  const session = await findSession(decoded.session);

  if (!session || !session.valid) return false;

  const user = (await getUserById(decoded.user)) || (await getWechatUserById(decoded.user));

  if (!user) return false;
  const accessToken = signJwt(
    { user: user.id, session: session.id },
    { expiresIn: '15m' }
  );

  return accessToken;
}
